<?php

set_include_path(get_include_path() . PATH_SEPARATOR . '..');

require_once 'simpletest/autorun.php';
require_once 'simpletest/mock_objects.php';
require_once 'database_engine/commands.php';

Mock::generate('IConnection');

class SelectCommandTests extends UnitTestCase
{
    /**
     * @return SimpleMock|IConnection
     */
    private function CreateMockConnection()
    {
        return new MockIConnection();
    }

    private $dataSourceMetadata1;
    private $dataSourceMetadata2;

    public function setUp()
    {
        $this->dataSourceMetadata1 = new TableMetadata('table01',
            array(
                'id' => array('type' => 'integer'),
                'value' => array('type' => 'string')
            )
        );
        $this->dataSourceMetadata2 = new TableMetadata('table02',
            array(
                'id' => array('type' => 'integer'),
                'link_id' => array('type' => 'integer'),
                'value' => array('type' => 'string')
            )
        );
    }

    public function testCondition()
    {
        $selectCommand = new SelectCommand();
        $selectCommand->AddSource($this->dataSourceMetadata1, 'table01_alias');

        $selectCommand->AddSimpleCondition('[id]', ConditionOperator::$Equals, '1');

        $this->assertEqual('SELECT t0.id AS id, t0.value AS value FROM table01 t0 WHERE (t0.id = 1)', $selectCommand->GetSql());
    }

    public function testConditionOnLookup()
    {
        $selectCommand = new SelectCommand();
        $selectCommand->AddSource($this->dataSourceMetadata1, 'table01_alias');
        $selectCommand->AddSimpleJoin($this->dataSourceMetadata2, 'table02_alias',
            '[table01_alias].[id]',
            '[table02_alias].[link_id]'
        );

        $selectCommand->AddSimpleCondition('[table01_alias].[id]', ConditionOperator::$Equals, '1');
        $selectCommand->AddSimpleCondition('[table02_alias].[id]', ConditionOperator::$Equals, '2');
        $selectCommand->AddSimpleCondition('[table02_alias].[link_id]', ConditionOperator::$Equals, '3');

        $this->assertEqual(
            'SELECT t0.id AS id, t0.value AS value, t1.id AS t1_id, t1.link_id AS t1_link_id, t1.value AS t1_value ' .
            'FROM table01 t0 INNER JOIN table02 t1 ON t0.id = t1.link_id WHERE (t0.id = 1) AND (t1.id = 2) AND (t1.link_id = 3)',
            $selectCommand->GetSql());
    }

    public function testSimpleCommand()
    {
        $selectCommand = new SelectCommand();
        $selectCommand->AddSource($this->dataSourceMetadata1, 'table01_alias');
        $selectCommand->AddSimpleJoin($this->dataSourceMetadata2, 'table02_alias',
            '[table01_alias].[id]',
            '[table02_alias].[link_id]'
        );

        $this->assertEqual(
            'SELECT t0.id AS id, '.
                't0.value AS value, '.
                't1.id AS t1_id, '.
                't1.link_id AS t1_link_id, '.
                't1.value AS t1_value ' .
            'FROM table01 t0 INNER JOIN table02 t1 ON t0.id = t1.link_id',
            $selectCommand->GetSql());

        $connection = $this->CreateMockConnection();

        $connection->setReturnReference('ExecuteReader', new EditableDataReaderStub(
            array(
                array(
                    'id' => 1,
                    'value' => 'value 1',
                    't1_id' => 2,
                    't1_link_id' => '1',
                    't1_value' => 'lookup value'
                )
            )
        ));
        
        $dataReader = $selectCommand->ExecuteReader($connection);

        $dataReader->Open();
        $dataReader->Next();
        
        $this->assertEqual(1,
            $dataReader->GetFieldValueByName('[table01_alias].[id]'));
        $this->assertEqual(1,
            $dataReader->GetFieldValueByName('[id]'));

        $this->assertEqual(1,
            $dataReader->GetFieldValueByName('id'));

        $this->assertEqual(2,
            $dataReader->GetFieldValueByName('[table02_alias].[id]'));

        $this->assertEqual(2,
            $dataReader->GetFieldValueByName('table02_alias.id'));

        $this->assertEqual('lookup value',
            $dataReader->GetFieldValueByName('[table02_alias].[value]'));

        $dataReader->Close();
    }

}

?>
